home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK2.toast / Development Kits (Disc 2) / QuickTime / Programming Stuff / Sample Code / Music Architecture / Embedding Instruments / TuneGeneration2.0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-06  |  10.2 KB  |  523 lines  |  [TEXT/KAHL]

  1.  
  2. /*--------------------------
  3.     Inclusions
  4. --------------------------*/
  5.  
  6. #include <QuickDraw.h>
  7. #include <Windows.h>
  8. #include <OSUtils.h>
  9. #include <FixMath.h>
  10.  
  11. #include "BigEasy2.h"
  12. #include "BigEasyTextish.h"
  13. #include "BigEasyDialogs.h"
  14. #include "MusicHelper.h"
  15. #include "FlatInstrumentTest.h"
  16.  
  17.  
  18. typedef unsigned long uuuulong;        /* hmmmm what is this, sheesh */
  19. // ••• typedef pascal void (*TunePlayCallBackProcPtr)(uuuulong *event,long seed,long refCon);
  20.  
  21.  
  22. #define kTuneSetNoteChannelsSelect kTuneLastSelector
  23. #define kTuneSetPartTransposeSelect kTuneLastSelector+1
  24.  
  25. #if 0
  26. enum
  27.     {
  28.     kTuneQuickStart = 8                /* Leave all the controllers where they are, ignore start time */
  29.     };
  30.  
  31. pascal ComponentResult TuneSetNoteChannels(TunePlayer tp,
  32.         unsigned long count,NoteChannel *noteChannelList,
  33.         TunePlayCallBackProcPtr playCallBackProc,
  34.         long refCon)
  35.      FIVEWORDINLINE(0x2F3C, 16, kTuneSetNoteChannelsSelect, 0x7000, 0xA82A);
  36.  
  37. pascal ComponentResult TuneSetPartTranspose(TunePlayer tp,
  38.         unsigned long part,
  39.         long transpose,
  40.         long velocityShift)
  41.      FIVEWORDINLINE(0x2F3C, 12, kTuneSetPartTransposeSelect, 0x7000, 0xA82A);
  42. #endif
  43. /*--------------------------
  44.     Limits and Konstants
  45. --------------------------*/
  46. enum
  47.     {
  48.     mOpen = 100,
  49.     mClose
  50.     };
  51.  
  52. #define kTunePlayerCount 3
  53.  
  54. typedef struct
  55.     {
  56.     WindowPtr w;
  57.  
  58.     NoteAllocator na;
  59.     TunePlayer tp[kTunePlayerCount];
  60.     short tpStep;
  61.     ToneDescription td;
  62.  
  63.     MusicScore ms;
  64.     Handle headerH,tuneH;
  65.     } Globals;
  66.  
  67. Globals g;
  68.  
  69.  
  70. /*--------------------------
  71.     Prototypes
  72. --------------------------*/
  73. static void DrawDoc(short n);
  74. static void ClickDoc(short n,Point p,short mods);
  75. static void KeyDoc(short n,short key,short code,short mods);
  76. static void IdleDoc(short n, Boolean front);
  77. static void GoAwayDoc(short n);
  78. static void ActivateDoc(short n);
  79. static void DeactivateDoc(short n);
  80. static void LetsQuit(short n,short menuItem,short menuRef);
  81. static void OpenWindow(short n,short menuItem,short menuRef);
  82. static void InitVars(void);
  83.  
  84. static pascal Boolean MyFilterProc(DialogPtr theDialog,
  85.         EventRecord *theEvent,short *itemHit);
  86.         
  87. /*--------------------------
  88.     Computer Programs
  89. --------------------------*/
  90.  
  91.  
  92.  
  93. #define kHeaderHeight 17
  94.  
  95. void DrawDoc(short n)
  96. /*
  97.  * Draws the window.
  98.  */
  99.     {
  100.     EraseRect(&gBigRect);
  101.     MoveTo(10,20);
  102.     DrawString("\pClick in window to play.");
  103.     MoveTo(10,40);
  104.     DrawString("\pOption-click to save movie.");
  105.     }
  106.  
  107.  
  108. #define knccount 10
  109. void ClickDoc(short n,Point p,short mods)
  110. /*
  111.  * Come here for a click in the window.
  112.  */
  113.     {
  114.     ComponentResult result;
  115.     NoteChannel nc[knccount];
  116.     Boolean ourNC;
  117.     short i;
  118.     TunePlayer tp;
  119.  
  120.     tp = g.tp[g.tpStep];
  121.     g.tpStep = (g.tpStep + 1 ) % kTunePlayerCount;
  122.  
  123.  
  124.     if(!g.headerH)
  125.         {
  126.         g.headerH = GetMusicScoreHeader(g.ms);
  127.         HLock(g.headerH);
  128.         }
  129.  
  130.     if(!g.tuneH)
  131.         {
  132.         g.tuneH = GetMusicScoreScore(g.ms);
  133.         HLock(g.tuneH);
  134.         }
  135.  
  136. #if 0
  137.     if(mods & shiftKey)
  138.         {
  139.         NoteRequest nr;
  140.  
  141.         ourNC = true;
  142.         result = NAStuffToneDescription(g.na,(p.h & 127) + 1,&nr.tone);
  143.         nr.polyphony = 1;
  144.         nr.typicalPolyphony = fixed1;
  145.         result = NANewNoteChannel(g.na,&nr,&nc[0]);
  146.         for(i = 1; i < knccount; i++)
  147.             nc[i] = nc[0];
  148.         result = TuneSetNoteChannels(tp,knccount,nc,nil,0);
  149.         }
  150.     else if (!(mods & controlKey))
  151. #endif
  152.         {
  153.         result = TuneSetHeader(tp,*(unsigned long **)g.headerH);
  154.         ourNC = false;
  155.         }
  156.  
  157. #if 0
  158.     for(i = 0; i < knccount; i++)
  159.         result = TuneSetPartTranspose(tp,i,((p.v & 63) - 32)<<8,0);
  160. #endif
  161.  
  162.     TuneQueue(tp,
  163.         *(unsigned long **)g.tuneH,
  164.         fixed1,
  165.         0,
  166.         0x7FFFFFFF,
  167.         kTuneStartNow,
  168. //        kTuneStartNow + ((mods & controlKey) ? kTuneQuickStart : 0),
  169.         nil,
  170.         0);
  171.  
  172.     while(Button());
  173.  
  174.     if(mods & (shiftKey | cmdKey))
  175.         {
  176.         TuneFlush(tp);
  177.         TuneStop(tp,0);
  178.         }
  179.  
  180.     if(ourNC)
  181.         NADisposeNoteChannel(g.na,nc[0]);
  182.  
  183.     if(mods & optionKey)
  184.         {
  185.         MusicMovie mm;
  186.         StandardFileReply sfr;
  187.  
  188.         StandardPutFile("\pSave Music Movie:","\pTunetest",&sfr);
  189.         if(sfr.sfGood)
  190.             {
  191.             mm = StartMusicMovie(&sfr.sfFile,g.headerH);
  192.             AddMusicMovieSample(mm,g.tuneH);
  193.             FinishMusicMovie(&mm);
  194.             }
  195.         }
  196.     }
  197.  
  198. #define kOptionA (0xFF & (unsigned short)'å')
  199.  
  200. void KeyDoc(short n,short key,short code,short mods)
  201.     {
  202.     MusicScore ms1,ms2;
  203.     Handle header,tune1,tune2;
  204.  
  205.     if(key >= 'a' && key <= 'z')
  206.         key += 'A' - 'a';
  207.  
  208.     if(key == 'A' || key == 'B' || key == kOptionA)
  209.         {
  210.         ms1 = NewMusicScore();
  211.         AddMusicScoreGMInstrument(ms1,1);        /* piano */
  212.         ms2 = NewMusicScore();
  213.         AddMusicScoreGMInstrument(ms2,1);        /* piano */
  214.  
  215.  
  216.         AddMusicScoreNote(ms1,1,60,100,600);
  217.         AddMusicScoreRest(ms1,20);
  218.         AddMusicScoreNote(ms2,1,80,70,600);
  219.         AddMusicScoreRest(ms2,300);
  220.  
  221.         header = GetMusicScoreHeader(ms1);
  222.         tune1 = GetMusicScoreScore(ms1);
  223.         tune2 = GetMusicScoreScore(ms2);
  224.  
  225.         HLock(header);
  226.         HLock(tune1);
  227.         HLock(tune2);
  228.  
  229.         TuneSetHeader(g.tp[0],*(unsigned long **)header);
  230.  
  231.         TuneQueue(g.tp[0],
  232.             *(unsigned long **)tune1,
  233.             fixed1,
  234.             0,
  235.             0x7FFFFFFF,
  236.             kTuneStartNewMaster,
  237.             nil,
  238.             0);
  239.  
  240.         TuneQueue(g.tp[0],
  241.             *(unsigned long **)tune2,
  242.             fixed1,
  243.             0,
  244.             0x7FFFFFFF,
  245.             0 + (key == 'A' ? 0 : kTuneDontClipNotes),
  246.             nil,
  247.             0);
  248.  
  249.  
  250.         if(key == kOptionA)
  251.             {
  252.             MusicMovie mm;
  253.             StandardFileReply sfr;
  254.     
  255.             StandardPutFile("\pSave Music Movie:","\pTunetest",&sfr);
  256.             if(sfr.sfGood)
  257.                 {
  258.                 mm = StartMusicMovie(&sfr.sfFile,header);
  259.                 AddMusicMovieSample(mm,tune1);
  260.                 AddMusicMovieSample(mm,tune2);
  261.                 FinishMusicMovie(&mm);
  262.                 }
  263.             }
  264.  
  265.         }
  266.     }
  267.  
  268. void IdleDoc(short n, Boolean front)
  269.     {
  270.     #pragma unused (n,front)
  271.     }
  272.  
  273. void GoAwayDoc(short n)
  274. /*
  275.  * Close that window...
  276.  */
  277.     {
  278.     UninstallWindow(n);
  279.     }
  280.  
  281. void ActivateDoc(short n)
  282.     {
  283. #pragma unused (n)
  284.      SetMenuItem(mClose,1,0,0,nil);                /* enable "Close" menu item        */
  285.     SetMenuItem(mOpen,-1,0,0,nil);                /* disable "Open" menu item        */
  286.     }
  287.  
  288. void DeactivateDoc(short n)
  289.     {
  290. #pragma unused (n)
  291.     SetMenuItem(mClose,-1,0,0,nil);                /* disable "Close" menu item    */
  292.     SetMenuItem(mOpen,1,0,0,nil);                /* enable "Open" menu item        */
  293.     }
  294.  
  295. void LetsQuit(short n,short menuItem,short menuRef)
  296.     {
  297. #pragma unused (n,menuItem,menuRef)
  298.  
  299.  
  300.     gQuitApp++;
  301.     }
  302.  
  303.  
  304. #define kWindowWidth 220
  305. #define kWindowHeight 140
  306.  
  307. void OpenWindow(short n,short menuItem,short menuRef)
  308.     {
  309. #pragma unused (n,menuItem,menuRef)
  310.     Rect r;
  311.  
  312.     SetRect(&r,0,0,kWindowWidth,kWindowHeight);
  313.     OffsetRect(&r,20,40);
  314.  
  315.     g.w = InstallWindow(1,"\p",&r,0,wCopyDraw,
  316.                                 DrawDoc,ClickDoc,KeyDoc,nil,
  317.                                 ActivateDoc,DeactivateDoc,IdleDoc);
  318.     }
  319.  
  320. Fixed FRandom(Fixed low,Fixed high);
  321. Fixed FRandom(Fixed low,Fixed high)
  322.     {
  323.     unsigned long x,y;
  324.     x = Random();
  325.     x &= 0xFFFF;
  326.     y = Random();
  327.     y &= 0xFFFF;
  328.     x <<= 16;
  329.     x = x % (high - low + 1);
  330.     x += low;
  331.     return (Fixed) x;
  332.     }
  333.  
  334.  
  335.  
  336. void DoBeat1(void);
  337. void DoBeat1(void)
  338.     {
  339.     long tu,d;
  340.  
  341.     tu = 100;
  342.     d = 300;
  343. /* 1 */
  344.     AddMusicScoreNote(g.ms,1,0x3200,127,d*5);
  345.     AddMusicScoreNote(g.ms,1,0x3244,100,d*5);
  346.  
  347.     AddMusicScoreNote(g.ms,2,60,120,d);
  348.     AddMusicScoreNote(g.ms,2,90,120,d);
  349.     AddMusicScoreRest(g.ms,tu*2);
  350. /* 2 */
  351.     AddMusicScoreNote(g.ms,2,63,120,d);
  352.     AddMusicScoreNote(g.ms,3,93,90,d);
  353.     AddMusicScoreNote(g.ms,3,88,90,d);
  354.     AddMusicScoreRest(g.ms,tu*2);
  355.  
  356. /* 3 */
  357.     AddMusicScoreNote(g.ms,2,60,120,d);
  358.     AddMusicScoreNote(g.ms,2,92,120,d);
  359.     AddMusicScoreRest(g.ms,tu*1);
  360.  
  361.     AddMusicScoreNote(g.ms,2,91,120,d);
  362.     AddMusicScoreRest(g.ms,tu*2);
  363. /* (4) */
  364.     AddMusicScoreNote(g.ms,2,92,120,d);
  365.     AddMusicScoreRest(g.ms,tu*1);
  366.  
  367.  
  368. /* 5 */
  369.     AddMusicScoreNote(g.ms,2,93,120,d);
  370.     AddMusicScoreNote(g.ms,2,60,120,d);
  371.     AddMusicScoreRest(g.ms,tu*2);
  372.  
  373. /* 6 */
  374.     AddMusicScoreNote(g.ms,1,0x2200,80,d*5);
  375.     AddMusicScoreNote(g.ms,1,0x2244,80,d*5);
  376.     AddMusicScoreNote(g.ms,2,63,120,d);
  377.     AddMusicScoreRest(g.ms,tu*2);
  378.  
  379.  
  380. /* 7 */
  381.     AddMusicScoreNote(g.ms,1,0x3900,80,d*5);
  382.     AddMusicScoreNote(g.ms,1,0x3244,80,d*5);
  383.     AddMusicScoreNote(g.ms,2,60,120,d);
  384.     AddMusicScoreNote(g.ms,2,92,120,d);
  385.     AddMusicScoreRest(g.ms,tu*1);
  386.  
  387.     AddMusicScoreNote(g.ms,3,92,120,d);
  388.     AddMusicScoreNote(g.ms,3,87,86,d);
  389.     AddMusicScoreNote(g.ms,2,91,80,d);
  390.     AddMusicScoreRest(g.ms,tu*1);
  391.  
  392. /* 8 */
  393.     AddMusicScoreNote(g.ms,2,91,120,d);
  394.     AddMusicScoreRest(g.ms,tu*1);
  395.  
  396.     AddMusicScoreNote(g.ms,2,92,120,d);
  397.     AddMusicScoreRest(g.ms,tu*1);
  398.     }
  399.  
  400.  
  401.  
  402. void InitVars()
  403. /*
  404.  * Called once at startup: yes, it
  405.  * inits the vars.
  406.  */
  407.     {
  408.     ComponentResult result;
  409.     short i;
  410.     Fixed p;
  411.     FlatInstrument *flatInstrument,*flatInstrument2;
  412.  
  413.     flatInstrument2 = CreateFlatInstrument();
  414.     flatInstrument = CreateFlatInstrumentFromSnd(1010);
  415.  
  416.     g.na = OpenDefaultComponent('nota',0);
  417.  
  418.  
  419.     g.tpStep = 0;
  420.     for(i = 0; i < kTunePlayerCount; i++)
  421.         g.tp[i] = OpenDefaultComponent('tune',0);
  422.  
  423.     g.ms = NewMusicScore();
  424.  
  425.     AddMusicScoreGMInstrument(g.ms,1);        /* piano */
  426. //    AddMusicScoreGMInstrument(g.ms,53);
  427. //    AddMusicScoreGMInstrument(g.ms,12);        /* vibraphone */
  428.  
  429.     AddMusicScoreFlatInstrument(g.ms,flatInstrument2);        /* ringmods */
  430.     AddMusicScoreFlatInstrument(g.ms,flatInstrument);        /* boomp */
  431.  
  432. #if 1
  433.     DoBeat1();
  434. #else
  435. #define kTimeUnit 400
  436.  
  437.     for(i = 0; i < 12; i++)
  438.         {
  439.         AddMusicScoreNote(g.ms,1,60+i,100,kTimeUnit*3/4);
  440.         AddMusicScoreNote(g.ms,2,60+i,80,kTimeUnit);
  441.  
  442.         p = i+60;
  443.         p<<=16;
  444.         AddMusicScoreNote(g.ms,2,i+55,
  445.                 80,kTimeUnit/2);
  446.         AddMusicScoreRest(g.ms,kTimeUnit/2);
  447.  
  448.         AddMusicScoreNote(g.ms,2,i+55,
  449.                 90,kTimeUnit/4);
  450.         AddMusicScoreRest(g.ms,kTimeUnit/4);
  451.  
  452.         AddMusicScoreNote(g.ms,2,i+55,
  453.                 80,kTimeUnit/4);
  454.         AddMusicScoreRest(g.ms,kTimeUnit/4);
  455.         }
  456.  
  457.     AddMusicScoreNote(g.ms,1,48,100,kTimeUnit*9);
  458.     AddMusicScoreNote(g.ms,2,52,60,kTimeUnit*9);
  459.     AddMusicScoreNote(g.ms,2,55,60,kTimeUnit*9);
  460.     AddMusicScoreNote(g.ms,2,(55L<<8) | 0x10,60,kTimeUnit*9);
  461.     AddMusicScoreNote(g.ms,1,72,60,kTimeUnit*9);
  462.     AddMusicScoreRest(g.ms,10);
  463.     AddMusicScoreNote(g.ms,1,79,100,kTimeUnit*9);
  464.     AddMusicScoreRest(g.ms,10);
  465.     AddMusicScoreNote(g.ms,1,84,90,kTimeUnit*9);
  466.     AddMusicScoreRest(g.ms,kTimeUnit*14);
  467. #endif
  468.  
  469.     }
  470.  
  471.  
  472.  
  473.  
  474. void AddMusicScoreNote(MusicScore ms,
  475.         short part,Fixed pitch,long velocity,TimeValue noteDuration);
  476. void AddMusicScoreRest(MusicScore ms,TimeValue restDuration);
  477.  
  478.  
  479.  
  480. void Bootstrap()
  481.     {
  482.     InitVars();
  483.  
  484. /*** File Menu ***/
  485.     InstallMenu("\pFile",nil,0);
  486.     InstallMenuItem("\pQuit/Q",LetsQuit,0);
  487.  
  488. /*** Edit Menu ***/
  489.     InstallEditMenu(nil,nil,nil,nil,nil);
  490.  
  491. /*** Picker Menu ***/
  492.     InstallMenu("\pTune",nil,0);
  493.  
  494.     OpenWindow(0,0,0);
  495.     }
  496.  
  497. void Hatstrap()
  498. /*
  499.   * clean up
  500.   */
  501.     {
  502.     short i;
  503.  
  504.     for(i = 0; i < kTunePlayerCount; i++)
  505.         CloseComponent(g.tp[i]);
  506.     }
  507.  
  508.  
  509. pascal Boolean MyFilterProc(DialogPtr theDialog,
  510.         EventRecord *theEvent,short *itemHit)
  511.     {
  512.     GrafPort *oldPort;
  513.  
  514.     GetPort(&oldPort);
  515.     SetPort(theDialog);
  516.  
  517.     if(theEvent->what == updateEvt && (DialogPtr)theEvent->message != theDialog)
  518.             HandleUpdateEvent(theEvent);
  519.  
  520.     SetPort(oldPort);
  521.     return false;
  522.     }
  523.